package excel

import (
	"errors"
	"fmt"
	"log"
	"math"
	"os"
	"regexp"
	"strconv"
	"time"

	"github.com/google/uuid"

	"github.com/xuri/excelize/v2"
)

// 读取excel
func readExcel(fileDir, sheetName string) ([][]string, error) {
	var err error
	f, err := excelize.OpenFile(fileDir)
	if err != nil {
		return nil, err
	}
	defer func() {
		if err = f.Close(); err != nil {
			log.Println(err)
		}
	}()

	// 获取sheet所有单元格
	rows, err := f.GetRows(sheetName)
	if err != nil {
		return nil, errors.New("读取表格失败")
	}

	return rows, nil
}

// verifyHeader 验证表头
func verifyHeader(temHeader, header [][]string) error {
	var (
		l1, l2 = len(temHeader), len(header)
		errStr = "表格表头不正确，请使用正确表格表头"
	)
	if l1 != l2 {
		return errors.New(errStr)
	}
	for i := 0; i < l1; i++ {
		l11, l22 := len(temHeader[i]), len(header[i])
		if l11 != l22 {
			return fmt.Errorf("第%d行的%s", i+1, errStr)
		}
		for j := 0; j < l11; j++ {
			if temHeader[i][j] != header[i][j] {
				return fmt.Errorf("第%d行，第%d列%s", i+1, j+1, errStr)
			}
		}
	}
	return nil
}

// GetUUID 获取uuid
func GetUUID() string {
	id, err := uuid.NewUUID()
	if err != nil {
		return ""
	}
	return id.String()
}

// stringMatchExport 根据字符串匹配内容
func stringMatchExport(str string, reg *regexp.Regexp) (res string, err error) {
	defer func() {
		if panicInfo := recover(); panicInfo != nil {
			err = errors.New("not match reg")
		}
	}()
	return reg.FindStringSubmatch(str)[1], nil
}

// 获取模板表头
func getTempHeader(tempHeaderTag, sheetName string) ([][]string, error) {
	dir, err := getTemp(tempHeaderTag)
	if err != nil {
		return nil, err
	}
	pwd, err := os.Getwd()
	if err != nil {
		return nil, err
	}
	excel, err := readExcel(pwd+dir, sheetName)
	if err != nil {
		return nil, err
	}

	if len(excel) <= 0 {
		return nil, errors.New("模板未设置表头")
	}
	return excel, nil
}

// 列唯一性校验
func (p *processor) uniqueFormat(uniqueKey string, col string, mappingField map[string]string) string {
	format, ok := mappingField[ExcelUniqueSign]
	if ok && format == "true" {
		uniqueKey += "_" + col
	}
	return uniqueKey
}

// 格式化时间
func (p *processor) dateFormat(col *string, mappingField map[string]string) (errList []string) {
	format, ok := mappingField[ExcelDateSign]
	if !ok || format == "" {
		return
	}
	// 初步判断是否是excel日期 44562
	if len(*col) == 5 {
		f, err := strconv.ParseFloat(*col, 64)
		t, err := excelize.ExcelDateToTime(f, false)
		if err == nil {
			*col = t.Format(format)
			return
		}
	}
	// 列举所有使用的excel时间格式
	formatSlc1 := []string{"2006/01", "2006-01", "200601", "2006/1", "2006-1", "20061"}              // 年月
	formatSlc2 := []string{"2006/01/02", "2006-01-02", "20060102", "2006/1/2", "2006-1-2", "200612"} // 年月日
	if len(format) <= 7 {
		for _, v := range formatSlc1 {
			location, err := time.ParseInLocation(v, *col, time.Local)
			if err != nil {
				continue
			}
			*col = location.Format(format)
			return
		}
	} else {
		for _, v := range formatSlc2 {
			location, err := time.ParseInLocation(v, *col, time.Local)
			if err != nil {
				continue
			}
			*col = location.Format(format)
			return
		}
	}
	return []string{"时间格式错误错误"}
}

// PageSize 切片分页数，用于切片分批操作
func PageSize(total, groupSize int) int {
	return int(math.Ceil(float64(total) / float64(groupSize))) //page总数
}
